package com.peaksport.framework.util;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;

import com.peaksport.framework.exception.PKDevException;

public class PKInvokeUtils {
	
	/**
	 * 反射对对象的属性字段赋值
	 * @param owner
	 * @param fieldName
	 * @param value
	 */
	public static void setFieldValue(Object owner, String fieldName, Object value) {
		try {
			Field field = PKClassUtils.getField(owner, fieldName);
			if (value == null) {
				field.set(owner, null);
				return;
			}
			if (PKPublicUtils.equalsAny(field.getType().getName(), boolean.class.getName(), Boolean.class.getName())) {
				boolean bValue = false;
				if (PKClassUtils.isAssignableFrom(String.class, value.getClass())) {
					bValue = PKPublicUtils.isTrue((String) value);
				} else if (value instanceof Integer) {
					bValue = ((Integer)value).intValue() == 1;
				} else if (value instanceof BigDecimal) {
					bValue = ((BigDecimal)value).intValue() == 1;
				} else {
					throw PKDevException.throwException("数据库类型[%s]解析到实体对象字段类型[%s]失败", value.getClass().getName(),field.getType().getName());
				}
				value = bValue;
			} else if (PKPublicUtils.equalsAny(field.getType().getName(), int.class.getName(), Integer.class.getName())) {
				int iValue = 0;
				if (value instanceof BigDecimal) {
					iValue =((BigDecimal)value).intValue();
				} else {
					throw PKDevException.throwException("数据库类型[%s]解析到实体对象字段类型[%s]失败", value.getClass().getName(),field.getType().getName());
				}
				value = iValue;
				
			} else if (PKPublicUtils.equalsAny(field.getType().getName(),long.class.getName(),Long.class.getName())) {
				if (value instanceof BigDecimal) {
					long lValue = ((BigDecimal)value).longValue();
					value = lValue;
				}
				
				
			}
			
			field.set(owner, value);
			
			
		} catch (Exception exc) {
			throw new PKDevException(exc.getMessage());
		}
	}
	

	public static Object getFieldValue(Object owner, String fieldName) {
		try {
			Field field = PKClassUtils.getField(owner, fieldName);
			return field.get(owner);
		} catch (Exception exc) {
			throw new PKDevException(exc.getMessage());
		}
	}
	
	public static Method getMethod(Object owner, String methodName, Class<?>... paramTypes) {
		Method method = null;
		Class<?> cls = owner.getClass();
		while (method == null && cls != null) {
			try {
				method = cls.getDeclaredMethod(methodName, paramTypes);
			} catch (Exception e) {}
			cls = cls.getSuperclass();
		}
		if (method == null) {
			throw new PKDevException(String.format("对象%s不存在方法%s(%s)",owner.getClass().getName(),methodName,paramTypes.toString()));
		}
		method.setAccessible(true);
		return method;
	}
	
	public static Object invokeMethod(Object owner, Method method, Object... paramValues) {
		Object returnValues = null;
		if (method == null) throw new PKDevException("方法不能为空！");
		try {
			returnValues = method.invoke(owner, paramValues);
		} catch (Exception e) {
			throw new PKDevException(e.getMessage());
		}
		return returnValues;
	}
	
	public static Object invokeMethod(Object owner, String methodName, Class<?>[] paramTypes, Object[] paramValues) {
		Method method = getMethod(owner, methodName, paramTypes);
		return invokeMethod(owner, method, paramValues);
	}
	
	
	/**
	 * 实例化class类
	 * @param clazz
	 * @param paramTypes 构造方法参数类型
	 * @param paramValues 构造方法参数值
	 * @return
	 */
	public static Object newInstance(Class<?> clazz, Class<?>[] paramTypes, Object[] paramValues) {
		try {
			PKDevUtils.verifyDevNull(clazz, "实例化class类不能为空.");
			Constructor<?> instC = null;
			Object instObj = null;
			instC = clazz.getDeclaredConstructor(paramTypes);
			instObj = instC.newInstance(paramValues);
			return instObj;
		} catch (Exception exc) {
			if (exc.getCause() instanceof ClassNotFoundException) throw new PKDevException(exc.getCause());
			throw PKDevException.throwException("类[%s]不存在[构造方法(%s)]",clazz.getName(),paramTypes == null ? "" : paramTypes.toString());
		}
	}
	
	/**
	 * 实例化class类
	 * @param className
	 * @param paramTypes 构造方法参数类型
	 * @param paramValues 构造方法参数值
     * @return
     */
	public static Object newInstance(String className, Class<?>[] paramTypes, Object[] paramValues) {
		Class<?> clazz = null;
		clazz = PKClassUtils.getClass(className);
		return newInstance(clazz,paramTypes,paramTypes);
	}
	
	/**
	 * 实例化无参数构造方法的class类
	 * @param className
	 * @return
	 */
	public static Object newInstance(String className) {
		return newInstance(className,null,null);
	}
	
	/**
	 * 实例化无参数构造方法的class类
	 * @param clazz
	 * @return
	 */
	public static Object newInstance(Class<?> clazz) {
		return newInstance(clazz,null,null);
	}
}
